
#include <string.h> 

#include "Utility.h"
#include "BSP_WG.h"
#include "WG.h"

#if 0
static uint8_t wgParity = 1;

void WG_Init(void){
	 wgParity = 1;
}

void WG_Config(uint8_t conf, void* param, uint32_t size){
	switch(conf){
	case WG_Conf_Pairty: {
		wgParity = *(uint8_t*)param;
	} 
	break;
	case WG_Conf_Time:{
		unsigned int* p = (unsigned int *)param;
		BSP_WG_Config(p[0] * 10, p[1] * 10);
	} 
	break;
	}
}

//获取WG 数据buf中第num位的值
static uint8_t WG_GetBit(const uint8_t* buf, uint8_t num){
	uint8_t i = num >> 3;
	uint8_t n = num & 0x07;
	uint8_t b = buf[i];
	
	return (b >> n) & 1;
}
//从高到低输出WG bit
void WG_SendBits(const uint8_t* buf, uint16_t nBits){
	uint16_t i;
	
	for(i = nBits; i > 0; ){
		i--;
		BSP_WG_SendBit(WG_GetBit(buf, i));
	}
}

//计算WG奇偶校验值
static void WG_GetParity(const uint8_t * buf, uint8_t nBits, int* s, int* e){
	uint8_t halfBits;
	uint8_t i;
	uint8_t front, back;
	
	//半数位
	halfBits = nBits >> 1; 
	front = 0;
	back = 0;
	
	//buf中的数据为LSB，高字节在后
	//由于韦根输出是最高位先输出，因此前半部分在高位
	
	//计算后半部分数据中'1'的个数
	for(i = 0; i < halfBits; i++){
		if(WG_GetBit(buf, i)){
			back++;
		}
	}
	//计算前半部分数据中'1'的个数
	for(; i < nBits; i++){
		if(WG_GetBit(buf, i)){
			front++;
		}
	}
	//前半部分偶校验，后半部分奇校验。
	*s = front & 1;
	*e = !(back & 1);
}

//发送一个WG数据帧
static void WG_SendFrame(int s, int e,
	const uint8_t * buf, uint8_t nBits){
	if(s >= 0){
		//发送偶校验位
		BSP_WG_SendBit(s); 
	}
	//发送数据，高位在前
	WG_SendBits(buf, nBits);
	if(e >= 0){
		//发送奇校验位
		BSP_WG_SendBit(e);
	}
}
//韦根反序输出
int WG_Send(const uint8_t * buf, uint8_t nBits, uint8_t parity){
	int s, e;
	
	if(nBits & 0x01){
		return 1; //发送比特数不为2的倍数
	}

	if(parity){
		//计算奇偶校验
		WG_GetParity(buf, nBits, &s, &e);
	}
	else{
		//不输出奇偶校验
		s = e = -1;
	}
	WG_SendFrame(s, e, buf, nBits);
	return 0;
}

int Wiegand_Send(uint8_t nBits, uint8_t reverse, const uint8_t * buf, uint8_t len){
	if(!reverse){
		uint8_t tbuf[16];
		memset(tbuf, 0, sizeof(tbuf));
		Mem_Reverse_Copy(tbuf, buf, len);
		return WG_Send(tbuf, nBits, wgParity);
	}
	else{
		return WG_Send(buf, nBits, wgParity);
	}
}

int Wiegand_SendBuf(uint8_t wgNum, WGBuf_T* wgBuf){
	uint8_t nbits = wgNum - 2;
	return Wiegand_Send(nbits, wgBuf->reverse, wgBuf->buf, wgBuf->len);
}
#endif
